package at.fhj.swd.pse.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * Represents a community entity
 * 
 * @author Helmut Kopf
 * 
 */

@Entity
@Table(name = "Communities")
public class Community implements Serializable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1525977316540708483L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private int m_id;

	@NotNull
	@Size(min = 1, max = 256)
	@Column(name = "Name")
	private String m_name;

	@NotNull
	@Size(min = 1, max = 2048)
	@Column(name = "Description")
	private String m_description;

	@NotNull
	@Size(min = 1, max = 256)
	@Column(name = "Topic")
	private String m_topic;

	@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinColumn(name = "FK_Admin")
	private User m_admin;

	@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
	@JoinTable(name = "CommunityUsers", 
				  joinColumns=@JoinColumn(name="Community_ID"), 
				  inverseJoinColumns=@JoinColumn(name="User_ID"))
	private Set<User> m_members = new HashSet<User>();

	@Column(name="Released")
	@NotNull
	private boolean m_released = false;
	
	
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinTable(name = "CommunityActivities",
				  joinColumns=@JoinColumn(name="Community_ID"),
				  inverseJoinColumns=@JoinColumn(name="Activity_ID"))	
	private Set<Activity> m_activities = new HashSet<Activity>();
	
	public Community()
	{
	}

	public int getID()
	{
		return this.m_id;
	}
	
	public void setID(final int id)
	{
		this.m_id = id;
	}	

	public String getName()
	{
		return this.m_name;
	}

	public void setName(final String name)
	{
		if (name != null)
		{
			this.m_name = name;
		}
		else
		{
			throw new NullPointerException("name");
		}
	}

	public String getDescription()
	{
		return this.m_description;
	}

	public void setDescription(final String description)
	{
		if (description != null)
		{
			this.m_description = description;
		}
		else
		{
			throw new NullPointerException("description");
		}
	}

	public String getTopic()
	{
		return this.m_topic;
	}

	public void setTopic(final String topic)
	{
		if (topic != null)
		{
			this.m_topic = topic;
		}
		else
		{
			throw new NullPointerException("topic");
		}
	}

	public User getAdministractor()
	{
		return this.m_admin;
	}

	public void setAdministractor(final User admin)
	{
		if (admin != null)
		{
			this.m_admin = admin;
		}
		else
		{
			throw new NullPointerException("admin");
		}
	}

	public boolean addMember(final User member)
	{
		if (member != null)
		{
			return this.m_members.add(member);
		}
		else
		{
			throw new NullPointerException("member");
		}
	}

	public boolean contains(final User member)
	{
		if (member != null)
		{
			return this.m_members.contains(member);
		}
		return false;
	}

	public List<User> getMembers()
	{
		return new ArrayList<User>(this.m_members);
	}

	public boolean getReleased()
	{
		return this.m_released;
	}

	public void setReleased(final boolean released)
	{
		this.m_released = released;
	}

	@Override
	public String toString()
	{
		String result = getClass().getSimpleName() + " ";
		result += "serialVersionUID: " + serialVersionUID;
		result += ", m_id: " + m_id;
		if (m_name != null && !m_name.trim().isEmpty())
			result += ", m_name: " + m_name;
		if (m_description != null && !m_description.trim().isEmpty())
			result += ", m_description: " + m_description;
		if (m_topic != null && !m_topic.trim().isEmpty())
			result += ", m_topic: " + m_topic;
		result += ", released: " + m_released;
		return result;
	}
	
	public List<Activity> getActivities() 
	{
		return new ArrayList<Activity>(m_activities);
	}

	public boolean addActivity(Activity activity) 
	{
		if (activity != null)
		{			
			return m_activities.add(activity);
		}
		else
		{
			throw new NullPointerException("activity");
		}		
	}	
}
